package ru.usu.gv.utils.exports;

import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

import javax.media.j3d.Canvas3D;
import javax.media.j3d.GraphicsConfigTemplate3D;
import javax.media.j3d.Screen3D;
import javax.media.j3d.View;

import ru.usu.gv.core.GraphCanvas;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfWriter;

/**
 @author Sergey Pupyrev 
 05.05.2007
 */

public class ExportTool
{
    private static OffScreenCanvas3D createOffScreenCanvas(float scale)
    {
        GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
        template.setDoubleBuffer(GraphicsConfigTemplate3D.UNNECESSARY);
        GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getBestConfiguration(template);

        //GraphCanvas.
        Canvas3D onScreenCanvas3D = GraphCanvas.getInstance();
        OffScreenCanvas3D offScreenCanvas3D = new OffScreenCanvas3D(gc);
        // Set the off-screen size based on a scale factor times the
        // on-screen size
        Screen3D sOn = onScreenCanvas3D.getScreen3D();
        Screen3D sOff = offScreenCanvas3D.getScreen3D();
        Dimension dim = sOn.getSize();
        dim.width *= scale;
        dim.height *= scale;
        sOff.setSize(dim);
        sOff.setPhysicalScreenWidth(sOn.getPhysicalScreenWidth() * scale);
        sOff.setPhysicalScreenHeight(sOn.getPhysicalScreenHeight() * scale);
        Point loc = onScreenCanvas3D.getLocationOnScreen();
        offScreenCanvas3D.setOffScreenLocation(loc);

        // attach the offscreen canvas to the view
        View view = GraphCanvas.getInstance().getUniverse().getViewer().getView();
        view.addCanvas3D(offScreenCanvas3D);
        return offScreenCanvas3D;
    }

    public static void writeJPEG(String path, float scale)
    {
        OffScreenCanvas3D offScreenCanvas3D = createOffScreenCanvas(scale);
        offScreenCanvas3D.saveToJPEG(path);

        GraphCanvas.getInstance().getUniverse().getViewer().getView().removeCanvas3D(offScreenCanvas3D);
    }

    public static void writePNG(String path, float scale)
    {
        OffScreenCanvas3D offScreenCanvas3D = createOffScreenCanvas(scale);
        offScreenCanvas3D.saveToPNG(path);

        GraphCanvas.getInstance().getUniverse().getViewer().getView().removeCanvas3D(offScreenCanvas3D);
    }

    public static void writeBMP(String path, float scale)
    {
        OffScreenCanvas3D offScreenCanvas3D = createOffScreenCanvas(scale);
        offScreenCanvas3D.saveToBMP(path);

        GraphCanvas.getInstance().getUniverse().getViewer().getView().removeCanvas3D(offScreenCanvas3D);
    }

    public static void writeHTML(String path, float scale)
    {
        OffScreenCanvas3D offScreenCanvas3D = createOffScreenCanvas(scale);
        int dotIndex = path.lastIndexOf(".");
        String simplePath = path.substring(0, dotIndex);
        String simpleName = simplePath.substring(simplePath.lastIndexOf(System.getProperty("file.separator")) + 1);
        offScreenCanvas3D.saveToJPEG(simplePath);
        GraphCanvas.getInstance().getUniverse().getViewer().getView().removeCanvas3D(offScreenCanvas3D);

        try
        {
            OutputStreamWriter out = new FileWriter(simplePath + ".html");
            out.write("<html>\n");
            out.write("<head><title>Image created by GraphVis</title></head>\n");
            out.write("<body>\n");
            out.write("  <table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n");
            out.write("      <tr><td><img src=\"" + simpleName + ".jpg\" border=\"0\" alt=\"\"/></td></tr>\n");
            out.write("  </table>\n");
            out.write("</body>\n");
            out.write("</html>\n");
            out.close();
        }
        catch (IOException e)
        {
            System.err.println(e.getMessage());
        }
    }

    public static void writePDF(String path, float scale)
    {
        OffScreenCanvas3D offScreenCanvas3D = createOffScreenCanvas(scale);
        int dotIndex = path.lastIndexOf(".");
        String simplePath = path.substring(0, dotIndex);
        String simpleName = simplePath.substring(simplePath.lastIndexOf(System.getProperty("file.separator")) + 1);
        offScreenCanvas3D.saveToJPEG(simplePath);
        GraphCanvas.getInstance().getUniverse().getViewer().getView().removeCanvas3D(offScreenCanvas3D);

        try
        {
            Document document = new Document();
            PdfWriter.getInstance(document, new FileOutputStream(simplePath + ".pdf"));
            Image jpg = Image.getInstance(simpleName + ".jpg");

            Rectangle rect = new Rectangle(PageSize.A4.height(), PageSize.A4.width());
            jpg.scaleToFit(PageSize.A4.height(), PageSize.A4.width());
            document.setPageSize(rect);

            document.open();
            document.add(jpg);

            //document.
            document.close();
        }
        catch (DocumentException de)
        {
            System.err.println(de.getMessage());
        }
        catch (IOException ioe)
        {
            System.err.println(ioe.getMessage());
        }
    }

    public static void print(float scale)
    {
        OffScreenCanvas3D offScreenCanvas3D = createOffScreenCanvas(scale);
        offScreenCanvas3D.print();

        GraphCanvas.getInstance().getUniverse().getViewer().getView().removeCanvas3D(offScreenCanvas3D);
    }

    public static void saveAVI(String path)
    {
        OffScreenCanvas3D offScreenCanvas3D = createOffScreenCanvas(1.0f);
        offScreenCanvas3D.saveToAVI(path);

        GraphCanvas.getInstance().getUniverse().getViewer().getView().removeCanvas3D(offScreenCanvas3D);
    }

}
